package ru.papergames.web.controllers;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import ru.common.hibernate.HibernateActionExecutor;
import ru.papergames.common.form.BattleServerCredentialsForm;
import ru.papergames.common.form.PcPlayerForm;
import ru.papergames.web.AppConstants;
import ru.papergames.web.blines.battle.BattleServersManager;
import ru.papergames.web.cache.PlayersManager;
import ru.papergames.web.services.users.LogonPcPlayer;
import ru.papergames.web.services.users.RegisterNewPcPlayer;

import javax.servlet.http.HttpServletRequest;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

/**
 * @author Alexander Troshanin
 */
@Controller
public class PcPlayersAuthController extends AbstractController {

    private static final Random rnd = new Random();

    private final HibernateActionExecutor hiber;

    public PcPlayersAuthController(@Qualifier("paperGamesHibernate") HibernateActionExecutor hiber) {
        this.hiber = hiber;
    }

    @RequestMapping(value = "/register.html", method = POST)
    public ModelAndView submitRegistrationForm(PcPlayerForm player) {
        ModelAndView mv = new ModelAndView("papergames/auth/registerUserPage");
        List<String> errors = new ArrayList<String>();
        mv.addObject("errors", errors);
        player.validate(errors);
        if (errors.isEmpty()) {
            hiber.execute(new RegisterNewPcPlayer(player, errors));
        }
        return mv;
    }

    @RequestMapping(value = "/check-already-logged-in.html", method = GET)
    public ModelAndView checkAlreadyLoggedIn(HttpServletRequest request) {
        ModelAndView mv = new ModelAndView("papergames/auth/checkAlreadyLoggedIn");
        mv.addObject("player", getPcPlayerForm(request));
        return mv;
    }

    @RequestMapping(value = "/logon.html", method = POST)
    public ModelAndView submitAuthUserForm(String username, String password, HttpServletRequest request) {
        PcPlayerForm player = hiber.execute(new LogonPcPlayer(username, password));
        if (player != null) {
            player = PlayersManager.getInstance().addActivePlayerAfterLogin(player);
            request.getSession().setAttribute(AppConstants.SESSION_USER, player);
        }
        ModelAndView mv = new ModelAndView("papergames/auth/logonResult");
        mv.addObject("player", player);
        return mv;
    }

    @RequestMapping(value = "/get-access-to-battle-server.html")
    public ModelAndView getAccessToBattleServer(HttpServletRequest request) {
        ModelAndView mv = new ModelAndView("papergames/auth/accessToBattleServer");
        PcPlayerForm player = getPcPlayerForm(request);
        if (player != null) {

            int secretKey = rnd.nextInt();

            BattleServerCredentialsForm serverCred = BattleServersManager.getInstance().addNewPlayerToBattleServer(player, secretKey);

            if (serverCred != null) {
                mv.addObject("secretKey", secretKey);
                mv.addObject("player", player);
                mv.addObject("battle_server_host", serverCred.getUserHost());
                mv.addObject("battle_server_port", serverCred.getUserPort());
                mv.addObject("success", true);
            } else {
                mv.addObject("success", false);
            }
        } else {
            mv.addObject("success", false);
        }
        return mv;
    }

    @RequestMapping(value = "/logoff.html")
    public ModelAndView submitLogoff(HttpServletRequest request) {
        PcPlayerForm player = getPcPlayerForm(request);
        request.getSession().removeAttribute(AppConstants.SESSION_USER);
        PlayersManager.getInstance().removeActivePlayerAfterLogof(player);
        return new ModelAndView("papergames/auth/logoffResult");
    }

}
